<?php

/**
 * 通用函数
 * 用于完成一些必要的封装，比如在新的类加载下无法调用的第三方扩展类，可以在这个地方进行封装
 * 
 * @author Kevin<xuhuahai@dangdang.com>
 * @version 1.0
 * @date April 13, 2015
 */

/**
 * 根据服务名和版本，返回类路径名
 *
 * @param
 *        	$service_name
 * @param
 *        	$service_version
 * @since Apr 13, 2015 1:34:08 PM
 * @access
 *
 */
// function get_service_class_name($service_name, $service_version) {
// $classname = "\\service\\" . $service_name . '_' . $service_version;
// $classname = str_replace ( ".", "_", $classname );
// $classname = str_replace ( "-", "_", $classname );
// $classname = str_replace ( "/", "_", $classname );
// return $classname;
// }

/**
 * 日志打印方法
 *
 * @param unknown $message        	
 */
function soa_debug($message, $category = 'default') {
	if(is_string($message)){
		log_output ( $category, LOG_LEVEL_DEBUG, $message );
	}else{
		log_output ( $category, LOG_LEVEL_DEBUG, var_export($message,true) );
	}
}
function soa_info($message, $category = 'default') {
	if(is_string($message)){
		log_output ( $category, LOG_LEVEL_INFO, $message );
	}else{
		log_output ( $category, LOG_LEVEL_INFO, var_export($message,true) );
	}
}
function soa_notice($message, $category = 'default') {
	if(is_string($message)){
		log_output ( $category, LOG_LEVEL_NOTICE, $message );
	}else{
		log_output ( $category, LOG_LEVEL_NOTICE, var_export($message,true) );
	}
}
function soa_warn($message, $category = 'default') {
	if(is_string($message)){
		log_output ( $category, LOG_LEVEL_WARN, $message );
	}else{
		log_output ( $category, LOG_LEVEL_WARN, var_export($message,true) );
	}
}
function soa_error($message, $category = 'default') {
	if(is_string($message)){
		log_output ( $category, LOG_LEVEL_ERROR, $message );
	}else{
		log_output ( $category, LOG_LEVEL_ERROR, var_export($message,true) );
	}
}
function soa_fatal($message, $category = 'default') {
	if(is_string($message)){
		log_output ( $category, LOG_LEVEL_FATAL, $message );
	}else{
		log_output ( $category, LOG_LEVEL_FATAL, var_export($message,true) );
	}
}

/**
 * 服务实例映射表
 */
$global_service_instances = array ();
$global_node_key = "";

function parse_node_key($service_config_file){
	$json_string = file_get_contents ( $service_config_file );
	$obj = json_decode ( $json_string, true );
	global $global_node_key;
	$global_node_key = $obj ['host'] . '#' . $obj ['port'];
}

/**
 * 返回服务的坐标值
 * 五维坐标：IP#Port#组#服务名#服务版本
 */
function get_service_coordinate($group,$service,$version){
	global $global_node_key;
	return $global_node_key . '#' . $group . '#' . $service . '#' . $version;
}

/**
 * 返回远程服务的坐标值
 * 五维坐标：Remote#组#服务名#服务版本
 */
function get_remote_service_coordinate($group,$service,$version){
	return 'Remote' . '#' . $group . '#' . $service . '#' . $version;
}

/**
 * 服务器地址
 */
function get_host($service_config_file) {
	$json_string = file_get_contents ( $service_config_file );
	$obj = json_decode ( $json_string, true );
	return $obj ['host'];
}

/**
 * 服务器端口
 */
function get_port($service_config_file) {
	$json_string = file_get_contents ( $service_config_file );
	$obj = json_decode ( $json_string, true );
	return $obj ['port'];
}

/**
 * 根据错误码返回 array of (错误码 + 错误消息)
 */
function get_status_code($errorCode) {
	global $global_error_codes;
	return array (
			'statusCode' => $errorCode,
			'statusDesc' => $global_error_codes [$errorCode] 
	);
}

/**
 * 合并配置
 * @param string $root_path               根目录
 * @param string $services_root_path      服务包所在的根目录
 * @param string $node_config_file_path   节点配置文件路径
 * @param string $output_config_file_path 合并后的输出配置文件路径
 */
function merge_config_files($root_path, $services_root_path, $node_config_file_path, $output_config_file_path) {
	$service_package_names = array ();
	$services_defines = array ();
	$directies = scandir($services_root_path);
	foreach ( $directies as $dir ) {
		if($dir == '.' || $dir == '..' || $dir == '.svn' || $dir == 'README'){
			continue;
		}
		if(is_file($services_root_path.DIRECTORY_SEPARATOR.$dir)){
			continue;
		}
		$service_package_names[] = $dir;
	}
	foreach ($service_package_names as $service_pak_name) {
		$service_pak_define_file = $services_root_path . DIRECTORY_SEPARATOR . $service_pak_name . DIRECTORY_SEPARATOR . 'services.json';
		if(!file_exists($service_pak_define_file)){
			soa_error('service package define file not found : '.$service_pak_define_file);
			continue;
		}
		$json_string = file_get_contents ( $service_pak_define_file );
		if(!$json_string){
			soa_error('read service package define failed : '.$service_pak_define_file);
			continue;
		}
		$arr = json_decode ( $json_string, true );
		if(is_null($arr) || !$arr){
			soa_error('decode service package define failed : '.$service_pak_define_file);
			continue;
		}
		$constants_file = $root_path . DIRECTORY_SEPARATOR . 'app' . DIRECTORY_SEPARATOR . 'services' . DIRECTORY_SEPARATOR . 
						  $service_pak_name . DIRECTORY_SEPARATOR . 'common' . DIRECTORY_SEPARATOR . 'constants.php';
		$functions_file = $root_path . DIRECTORY_SEPARATOR . 'app' . DIRECTORY_SEPARATOR . 'services' . DIRECTORY_SEPARATOR . 
						  $service_pak_name . DIRECTORY_SEPARATOR . 'common' . DIRECTORY_SEPARATOR . 'functions.php';
		$profile_file   = $root_path . DIRECTORY_SEPARATOR . 'app' . DIRECTORY_SEPARATOR . 'services' . DIRECTORY_SEPARATOR . 
						  $service_pak_name . DIRECTORY_SEPARATOR . 'common' . DIRECTORY_SEPARATOR . 'profile.' . PROFILE . '.php';
		if(file_exists($constants_file)){
			require_once $constants_file;
		}
		if(file_exists($functions_file)){
			require_once $functions_file;
		}
		if(file_exists($profile_file)){
			require_once $profile_file;
		}
		foreach ( $arr as $service_define ) {
			$service_define['class'] = '\\services\\' . $service_pak_name . '\\service\\' . $service_define['class'];
			$services_defines[] = $service_define;
		}
	}
	if(empty($services_defines)){
		soa_error('Not found services!');
		return -1;
	}
// 	print_r($services_defines);
	$node_json_string = file_get_contents ( $node_config_file_path );
	$node_obj = json_decode ( $node_json_string, true );
	$result = array ();
	$result['host'] = $node_obj ['host'];
	$result['port'] = $node_obj ['port'];
	$result['group'] = $node_obj ['group'];
	$result['services'] = $services_defines;
	$output_content = json_encode($result,JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
	if(file_put_contents($output_config_file_path,$output_content)){
		return 0;
	}else{
		return -1;
	}
}

/**
 * 服务实例初始化
 *
 * @param unknown $service_config_file        	
 */
function init_service_intances($service_config_file) {
	global $global_service_instances;
	$json_string = file_get_contents ( $service_config_file );
	$obj = json_decode ( $json_string, true );
	// print_r ( $obj );
	$group = $obj ['group'];
	foreach ( $obj ['services'] as $snode ) {
		$key = $group . '*'. $snode ['service'] . '*' . $snode ['version'];
		$clsname = $snode ['class'];
		$global_service_instances [$key] = $clsname;
		soa_info ( 'register service : ' . $group . ',' . $snode ['service'] . ',' . $snode ['version'] . ',' . $snode ['class'] );
	}
	// print_r ( $global_service_instances );
}

// /**
//  * 搜寻服务实例
//  *
//  * @param unknown $service_name        	
//  * @param unknown $service_version        	
//  */
// function find_service_instance($service_name, $service_version) {
// 	global $global_service_instances;
// 	$key = $service_name . '*' . $service_version;
// 	// print_r ( $global_service_instances );
// 	if (isset ( $global_service_instances [$key] )) {
// 		return $global_service_instances [$key];
// 	}
// 	return NULL;
// }

/**
 * 生成一个全局唯一的ID 主要来生成permanent_id & trace_id
 * 暂时保留原生成方法(ycg@0608)
 *
 * @return string
 */
function gen_guid() {
	$guid = '';
	$mt = explode(' ', microtime());
	$ms = '00' . $mt[0];
	$start = strlen($ms);
	$ms = substr($ms, $start - 3, 3);
	$guid = date('YmdHis') . $ms . rand(100000, 999999) . rand(100000, 999999) . rand(100000, 999999);
	return $guid;
}

/**
 * 返回当前秒值(浮点数形式)
 * @return number
 */
function get_now_microtime_float(){
	list($usec, $sec) = explode(" ", microtime());
	return ((float)$usec + (float)$sec);
}

/**
 * 根据变量名字取全局变量
 * @param unknown $name
 */
function  get_global_value($name){
	global $$name;
	return $$name;
}

